package com.echo.week02.jvm;

import java.nio.ByteBuffer;

/**
 * @Author echo
 * @Description 直接内存案例
 * @Date 2023/9/27.
 * @Version 1.0
 */
public class ByteBufferCompare {
    public static void main(String[] args) {
        //分配比较
//        allocateCompare();
        //读写比较
        operateCompare();
    }

    /**
     * 直接内存和对内存的分配空间比较
     * 结论：在数据量提升时，直接内存相比非直接内存的申请，有很严重的性能问题
     */
    public static void allocateCompare() {

        int time = 1000*10000; //操作次数  1千万
        long startTime = System.currentTimeMillis();
        for (int i = 0; i <time; i++) {
            //分配一个新的字节缓存区
            //非直接内存分配申请
            ByteBuffer buffer = ByteBuffer.allocate(2);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("在进行"+time+"次分配操作时，堆内存分配耗时："+(endTime-startTime)+"ms");

        long startTimeHeap = System.currentTimeMillis();
        for (int i = 0; i < time; i++) {
            //分配新的字节缓存区
            // 直接内存分配申请
            ByteBuffer.allocateDirect(2);
        }
        long endTimeHeap = System.currentTimeMillis();
        System.out.println("在进行"+time+"次分配操作时，直接内存 分配耗时："+(endTimeHeap - startTimeHeap)+"ms");
    }


    /**
     * 直接内存和堆内存的读写性能比较
     * 结论：直接内存在直接的IO操作上，在频繁的读写时，会有显著的性能提升
     */
    public static void operateCompare(){
        int time = 100*1000*10000; //操作次数
        ByteBuffer buffer = ByteBuffer.allocate(2 * time);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i <time; i++) {
            //putChar(char value) 用来写入chat值的相对put方法
            buffer.putChar('a');
        }
        buffer.flip();
        for (int i = 0; i <time; i++) {
            buffer.getChar();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("在进行"+time+"次读写操作时，非直接内存 读写耗时："+(endTime-startTime)+"ms");

        ByteBuffer buffer1 = ByteBuffer.allocateDirect(2 * time);
        long startTimeDirect = System.currentTimeMillis();
        for (int i = 0; i <time ; i++) {
            //putChar(char value) 用来写入chat值的相对put方法
            buffer1.putChar('a');
        }
        buffer1.flip();
        for (int i = 0; i <time ; i++) {
            buffer1.getChar();
        }
        long endTimeDirect = System.currentTimeMillis();
        System.out.println("在进行"+time+"次读写操作时，直接内存 读写耗时："+(endTimeDirect-startTimeDirect)+"ms");
    }
}
